package com.ctsi.ssdc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.ctsi.ssdc.admin.domain.CscpUser;
import com.ctsi.ssdc.admin.domain.CscpUserDetail;
import com.ctsi.ssdc.admin.domain.CscpUserRole;
import com.ctsi.ssdc.admin.domain.dto.CscpUserDTO;
import com.ctsi.ssdc.admin.domain.dto.CscpUserDetailDTO;
import com.ctsi.ssdc.admin.domain.dto.CscpUserRoleDTO;
import com.ctsi.ssdc.admin.repository.CscpUserDetailRepository;
import com.ctsi.ssdc.admin.repository.CscpUserRepository;
import com.ctsi.ssdc.admin.service.CscpUserDetailService;
import com.ctsi.ssdc.admin.service.CscpUserRoleService;
import com.ctsi.ssdc.admin.service.CscpUserService;
import com.ctsi.ssdc.admin.service.impl.CscpUserDetailServiceImpl;
import com.ctsi.ssdc.admin.service.mapper.CscpUserDetailMapper;
import com.ctsi.ssdc.security.SecurityHxUtils;
import com.ctsi.ssdc.service.SSOService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class SSOServiceImpl implements SSOService {

    @Resource
    private CscpUserService cscpUserService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private CscpUserRoleService cscpUserRoleService;
    @Resource
    private CscpUserDetailRepository cscpUserDetailRepository;
    @Resource
    private CscpUserRepository cscpUserRepository;
    @Value("${ctsi.sso-request-url}")
    private String SSO_URL;

    private static String DEFAULT_PWD = "ctsi@789";
    public static final long ADMIN_PERMISSIONS = 1;


    @Override
    public Boolean userExist(CscpUserDetailDTO userDetail) {
        CscpUserDTO one = cscpUserService.findOne(userDetail.getUserId());
        return ObjectUtil.isNotEmpty(one);
    }

    @Override
    public CscpUserDetailDTO fetchSSOUserDetail(String token) {
        if (StringUtils.isBlank(token) || token.length()<7) return null;
        if (token.substring(0,7).equals("Bearer ")) {
            token = token.substring(7);
        }
        RestTemplate template = new RestTemplate();
        String url = SSO_URL;
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
        paramMap.add("token", token);
        HttpHeaders headers = new HttpHeaders();
//        headers.add("User-Agent", "Chrome/69.0.3497.81 Safari/537.36");
        headers.add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36");
        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Expose-Headers", "X-Requested-With");
        headers.add("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH");
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(paramMap, headers);
        ResponseEntity<String> response = template.postForEntity(url, httpEntity, String.class);
        //1、解析json，如果数据库不存在该用户信息，将用户信息存入数据库
        Map map = JSONObject.parseObject(response.getBody(), Map.class);
        if (map == null || !map.get("code").equals(200)) {
            log.warn("--------------------------------------------/n/t" +
                            "发生故障!\n\t" +
                            "token: {} \n\t" +
                            "时间: {}\n\t" +
                            "返回内容: \n{}\n\t" +
                            "--------------------------------------------",
                    token,
                    new Date(),
                    response);
        }
//        System.out.println(map);
        Object data = map.get("data");
        CscpUserDetailDTO cscpUserDetail = new CscpUserDetailDTO();
        BeanUtil.copyProperties(data, cscpUserDetail);
        return cscpUserDetail;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CscpUserDetailDTO saveUser(CscpUserDetailDTO userDetail) {
        String adminFlag = userDetail.getAdminFlag();
        if (("0").equals(adminFlag)) {
            // 管理员


//            CscpUserDetailDTO userDetailDTO = insert(cscpUserDetail, DEFAULT_PWD);
            CscpUser cscpUser = new CscpUser();
            cscpUser.setId(userDetail.getUserId());
            cscpUser.setUsername(userDetail.getUsername());
            cscpUser.setPassword(this.passwordEncoder.encode(DEFAULT_PWD));
            this.cscpUserRepository.insert(cscpUser);

            Long tenantId = null;
            //1478649882954985474
            Long dtoTenantId = userDetail.getTenantId();
            if (dtoTenantId == null) {
                Long currentUserId = SecurityHxUtils.getCurrentUserId();
                tenantId = this.cscpUserDetailRepository.selectByUserId(currentUserId).getTenantId();
            } else {
                tenantId = dtoTenantId;
            }
            userDetail.setTenantId(tenantId);
            CscpUserDetail cscpUserDetail = new CscpUserDetail();
            BeanUtil.copyProperties(userDetail, cscpUserDetail);
            cscpUserDetail.setRegisterTime(ZonedDateTime.now());
            this.cscpUserDetailRepository.insert(cscpUserDetail);
            // 绑定权限
            List<CscpUserRole> cscpUserRoles = cscpUserRoleService.selectByUserId(userDetail.getUserId());
            boolean flag = true;
            for (CscpUserRole cscpUserRole : cscpUserRoles) {
                if (cscpUserRole.getRoleId() == ADMIN_PERMISSIONS) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                CscpUserRoleDTO cscpUserRoleDTO = new CscpUserRoleDTO();
                cscpUserRoleDTO.setUserId(userDetail.getUserId());
                cscpUserRoleDTO.setRoleId(ADMIN_PERMISSIONS);
                CscpUserRoleDTO userRoleDTO = cscpUserRoleService.insert(cscpUserRoleDTO);
                if (userRoleDTO == null) throw new RuntimeException("权限申请失败!!");
            }
        } else {
            // 非管理员
        }
        return userDetail;
    }
}
